/*
 * Copyright (c) 2018, dreamkaylee@foxmail.com All Rights Reserved.
 */

package com.vip.jwt.common.exception;

import com.vip.jwt.common.entity.R;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authz.UnauthorizedException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.converter.HttpMessageNotReadableException;
import org.springframework.validation.BindException;
import org.springframework.validation.BindingResult;
import org.springframework.web.HttpRequestMethodNotSupportedException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import org.springframework.web.multipart.support.MissingServletRequestPartException;

import java.util.Objects;

/**
 * 全局的的异常拦截器（拦截所有的控制器）（带有@RequestMapping注解的方法上都会拦截）
 * @author vip
 * @date 2020年4月1日
 */
@RestControllerAdvice
public class BaseControllerExceptionHandler {

    private Logger logger = LoggerFactory.getLogger(this.getClass());

    /**
     * 上传的文件不存在
     * @param e
     * @return
     */
    @ExceptionHandler(MissingServletRequestPartException.class)
    public Object noRequestPart(MissingServletRequestPartException e){
        logger.error("上传的文件不存在:", e);
        return R.error().code(ExceptionEnum.FILE_NOT_FOUND.getCode()).message(ExceptionEnum.FILE_NOT_FOUND.getMessage());
    }

    /**
     * 拦截验证异常
     * @param e
     * @return
     */
    @ExceptionHandler(BindException.class)
    public Object valid(BindException e) {
        logger.error("验证异常:", e);
        BindingResult bindingResult = e.getBindingResult();
        return R.error().code(1).message(Objects.requireNonNull(bindingResult.getFieldError()).getDefaultMessage());
    }

    /**
     * 请求方式错误
     * @param e
     * @return
     */
    @ExceptionHandler(HttpRequestMethodNotSupportedException.class)
    public Object typeFount(HttpRequestMethodNotSupportedException e) {
        logger.error("请求方式错误:", e);
        return R.error().code(ExceptionEnum.TYPE_ERROR.getCode()).message(ExceptionEnum.TYPE_ERROR.getMessage());
    }

    /**
     * 参数不正确
     * @param e
     * @return
     */
    @ExceptionHandler(HttpMessageNotReadableException.class)
    public Object typeFount(HttpMessageNotReadableException e) {
        logger.error("参数传递不正确(表单、json):", e);
        return R.error().code(ExceptionEnum.PARAM_ERROR.getCode()).message(ExceptionEnum.PARAM_ERROR.getMessage());
    }

    /**
     * Token验证错误
     * @param e
     * @return
     */
    @ExceptionHandler(AuthenticationException.class)
    public Object tokenError(AuthenticationException e){
        logger.error("Token验证错误:", e);
        return R.error().code(ExceptionEnum.TOKEN_INVALID.getCode()).message(ExceptionEnum.TOKEN_INVALID.getMessage());
    }

    /**
     * 权限不足
     * @param e
     * @return
     */
    @ExceptionHandler(UnauthorizedException.class)
    public Object authException(UnauthorizedException e){
        logger.error("权限不足:", e);
        return R.error().code(ExceptionEnum.UNAUTHORIZED.getCode()).message(ExceptionEnum.UNAUTHORIZED.getMessage());
    }

    /**
     * 自定义异常
     * @param e
     * @return
     */
    @ExceptionHandler(MyException.class)
    public Object notFount(MyException e) {
        logger.error("自定义异常:", e);
        return R.error().code(e.getCode()).message(e.getMessage());
    }

    /**
     * 拦截未知的运行时异常
     * @param e
     * @return
     */
    @ExceptionHandler(RuntimeException.class)
    public Object notFount(RuntimeException e) {
        logger.error("运行时异常:", e);
        return R.error().code(ExceptionEnum.SERVER_ERROR.getCode()).message(ExceptionEnum.SERVER_ERROR.getMessage());
    }

}
  